//为一个POJO添加事件支持(这里窃取了Java中POJO的定义)
//TODO: to be tested
define(['./mixin'], function(Mixin) {

  if(!Array.prototype.remove){
    Array.prototype.remove = function(from, to) {
      var rest = this.slice((to || from) + 1 || this.length);
      this.length = from < 0 ? this.length + from : from;
      return this.push.apply(this, rest);
    };
  }

  return function(cls) {
    var eventImp = {

      _initEvent: function(){
        this.__eventMap = this.__eventMap || {};
      },

      _findEventPath: function(eventPath, create) {
        var self = this;
        //这里不考虑IE这种垃圾
        var events = eventPath.trim().split(':');
        var pointer = self.__eventMap; // 学过C语言的可以理解这个东西
        for (var i = 0; i < events.length; ++i) {
          if (pointer[events[i]] === undefined) {
            if(create){
              pointer[events[i]] = {
                __handlers: [],
                __targets: []
              };
            }else{
              return null;
            }
          }
          pointer = pointer[events[i]];
        }

        if (pointer === self.__eventMap) {
          return null;
        }
        return pointer;
      },

      _findHandlerSet: function(eventPath) {
        var self = this;
        var handlerSet = [];
        var events = eventPath.trim().split(':');
        var pointer = self.__eventMap;

        for (var i = 0; i < events.length; ++i) {
          pointer = pointer[events[i]];
          if (pointer === undefined) break;
          handlerSet = handlerSet.concat(pointer.__handlers);
        }

        return handlerSet;
      },

      _onSingleEvent: function(eventPath, handler){
        var self = this;
        var eventSet = self._findEventPath(eventPath, true);

        if(eventSet === null)return;
        eventSet.__handlers.push(handler);
      },

      // 可以on多个事件，用空格分隔
      on: function(eventPath, handler) {
        var self = this;
        var events = eventPath.trim().split(' ');

        // 这里发现一个bug，当String中不包含制定字符串的时候，slice方法返回本字符串，而非一个数组
        if(events instanceof Array){
          for(var i = 0; i < events.length; ++i){
            self._onSingleEvent(events[i], handler);
          }
        }else{
          self._onSingleEvent(events, handler);
        }

        //支持链式操作
        return self;
      },

      _fireSingleEvent: function(eventName, args){
        var self = this;
        if(!eventName)return;
        var eventPath = self._findEventPath(eventName);
        if(!eventPath)return;
        var handlers = eventPath.__handlers;
        var targets  = eventPath.__targets;
        var i;
        var handlerCount = handlers.length;
        var targetCount = targets.length;

        args = args || {};
        args.__path = eventName;

        for(i = 0; i < handlerCount; ++i){
          //如果某个回调函数返回false，则停止冒泡
          if(handlers[i](args) === false)return false;
        }

        for(i = 0; i < targetCount; ++i){
          targets[i].fire && targets[i].fire(eventName, args);
        }

        return true;
      },

      //fire也可以同时发出多个事件 
      fire: function(eventPath, args) {
        var self = this;
        var events = eventPath.trim().slice(' ');

        setTimeout(function(){
          // 这里发现一个bug，当String中不包含制定字符串的时候，slice方法返回本字符串，而非一个数组
          if(events instanceof Array){
            for(var i = 0; i < events.length; ++i){
              if(self._fireSingleEvent(events[i], args) === false)break;
            }
          } else {
            self._fireSingleEvent(events, args);
          }
        }, 0);
      },

      //频繁的off操作注定低效
      off: function(eventPath, handler) {
        var self = this;
        var events = eventPath.trim().slice(':');
        var pointer = self.__eventMap;
        var i;

        for(i = 0; i < events.length; ++i){
          pointer = pointer[event[i]];
        }

        if(pointer !== self.__eventMap){
          if(handler){

            var handlers = pointer.__handlers;
            var count = handlers.length;
            var newHandlerSet = [];

            for(i = 0; i < count; ++i){
              if(handlers[i] !== handler){
                newHandlerSet.push(handlers[i]);
              }
            }
            pointer.__handlers = newHandlerSet;

          }else{
            pointer.__handlers = [];
          }
        }

        //支持链式操作
        return self;
      },

      addTarget: function(eventName, target){
        var self = this;
        var events = eventPath.trim().slice(' ');
        var eventCount = events.length;

        for(var i = 0; i < eventCount; ++i){
          var eventPath = self._findEventPath(eventName, true);
          eventPath.__targets.push(target);
        }
      },

      removeTarget: function(eventName, target){
        var self = this;
        var events = eventPath.trim().slice(' ');
        var eventCount = events.length;
        var i,j, targetCount;

        for(i = 0; i < eventCount; ++i){
          var eventPath = self._findEventPath(eventName, false);
          if(eventPath !== null){
            targetCount = eventPath.__targets.length;
            for(j = 0; j < targetCount; ++j){
              if(targets[i] === target){
                targets.remove(i);
                break;
              }
            }
          }else{
            eventPath.__targets = [];
          }
        }

        return self;
      }
    };

    Mixin(cls.prototype, eventImp);
  };
});

